home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Die Speccy' 97
/
Die Speccy' 97.iso
/
amiga_system
/
the_aminet
/
comm
/
tcp
/
mufs_telnetd.lha
/
telnetd2_0.lha
/
telnetd-2.0
/
source
/
fakesr
/
fakesr.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-15
|
5KB
|
187 lines
#include <exec/types.h>
#include <exec/io.h>
#include <exec/errors.h>
#include <exec/devices.h>
#include <proto/exec.h>
#include "fakesr.h"
#include "fakesrprivate.h"
#define NewList(list) {(list)->lh_Head=(struct Node *)&(list)->lh_Tail;(list)->lh_TailPred=(struct Node *)&(list)->lh_Head;(list)->lh_Tail=NULL;}
ULONG __asm _FakeSer_BeginIO(register __a1 void *IORequest,register __a6 struct FakeSerDevice *FakeSerBase)
{
struct FSRUnit *Unit;
Unit=(struct FSRUnit *)((struct IORequest *)IORequest)->io_Unit;
if (!Unit || !Unit->fsru_BeginIO) return 0;
return Unit->fsru_BeginIO(IORequest);
}
ULONG __asm _FakeSer_AbortIO(register __a1 void *IORequest,register __a6 struct FakeSerDevice *FakeSerBase)
{
struct FSRUnit *Unit;
Unit=(struct FSRUnit *)((struct IORequest *)IORequest)->io_Unit;
if (!Unit || !Unit->fsru_AbortIO) return 0;
return Unit->fsru_AbortIO(IORequest);
}
int AddUnit(struct FakeSerDevice *FakeSerBase,struct FSRUnit *Unit)
/* returns zero for no error */
/* returns 1 for bad address/other mem error */
/* returns to for non-uniqe unit */
{
struct FSRUnit *CurUnit;
void *SysBase;
SysBase=*((void **)0x00000004);
if (!FakeSerBase || !Unit) return 1;
for (CurUnit=(struct FSRUnit *)FakeSerBase->fsd_UnitList.lh_Head;
CurUnit->fsru_Node.ln_Succ && CurUnit->fsru_Num != Unit->fsru_Num;
CurUnit=(struct FSRUnit *)CurUnit->fsru_Node.ln_Succ);
if (CurUnit->fsru_Node.ln_Succ) {
/* we have a duplicated unit # */
return 2;
}
else AddTail(&FakeSerBase->fsd_UnitList,Unit);
return 0;
}
ULONG CtlUnit_BeginIO(void *IORequest)
{
struct IOStdReq *IOReq;
struct FakeSerDevice *FakeSerBase;
struct FSRUnit *Unit;
int Err;
void *SysBase;
SysBase=*((void **)0x00000004);
if (!IORequest) return 0;
IOReq=IORequest;
FakeSerBase=(struct FakeSerDevice *)IOReq->io_Device;
if (!FakeSerBase) return 0;
if (IOReq->io_Flags & IOF_QUICK) {
IOReq->io_Flags &= ~(IOF_QUICK);
/* we don't explicitly support quick io */
}
IOReq->io_Error=0;
switch (IOReq->io_Command) {
case FSRCMD_ADDUNIT:
Unit=(struct FSRUnit *)IOReq->io_Data;
if (Unit->fsru_Num == FSR_UNITNONE) {
Forbid();
for (Unit->fsru_Num=MAXRESERVEDUNIT+1;(Err=AddUnit(FakeSerBase,Unit))==2;Unit->fsru_Num++)
;
Permit();
} else {
Forbid();
Err=AddUnit(FakeSerBase,Unit);
Permit();
}
if (Err) {
if (Err==1) IOReq->io_Error=IOERR_BADADDRESS;
else IOReq->io_Error=FSRCTLERR_NONUNIQUE;
}
ReplyMsg(&IOReq->io_Message);
break;
case FSRCMD_REMUNIT:
Unit=(struct FSRUnit *)IOReq->io_Data;
Forbid();
Remove(Unit);
Permit();
ReplyMsg(&IOReq->io_Message);
break;
default:
IOReq->io_Error=IOERR_NOCMD;
ReplyMsg(&IOReq->io_Message);
}
}
ULONG CtlUnit_AbortIO(void *IORequest)
{
return 0; /* We do stuff quickly anyway */
}
void __saveds __asm _UserLibInit(register __a6 struct FakeSerDevice *FakeSerBase )
{
void *SysBase;
SysBase=*((void **)0x00000004);
if (!FakeSerBase) return;
NewList(&FakeSerBase->fsd_UnitList);
FakeSerBase->fsd_CtlUnit.fsru_Num=FSR_CTLUNIT;
FakeSerBase->fsd_CtlUnit.fsru_BeginIO=CtlUnit_BeginIO;
FakeSerBase->fsd_CtlUnit.fsru_AbortIO=CtlUnit_AbortIO;
FakeSerBase->fsd_CtlUnit.fsru_Open=NULL;
FakeSerBase->fsd_CtlUnit.fsru_Close=NULL;
Forbid(); /* Lock the list */
AddUnit(FakeSerBase,&FakeSerBase->fsd_CtlUnit);
Permit();
}
void __saveds __asm _UserLibCleanup(register __a6 struct FakeSerDevice *FakeSerBase)
{
return; /* No cleanup work required */
}
void __saveds _UserLibOpen(struct FakeSerDevice *FakeSerBase, void *IORequest, LONG UnitNum,LONG Flags)
{
struct FSRUnit *Unit;
struct IORequest *IOReq;
void *SysBase;
SysBase=*((void **)0x00000004);
IOReq=IORequest;
if (!IOReq) return;
IOReq->io_Message.mn_Node.ln_Type=NT_REPLYMSG;
Forbid(); /* We Forbid()-protect the unit list */
for (Unit=(struct FSRUnit *)FakeSerBase->fsd_UnitList.lh_Head;Unit->fsru_Node.ln_Succ;Unit=(struct FSRUnit *)Unit->fsru_Node.ln_Succ)
if (Unit->fsru_Num==UnitNum) {
IOReq->io_Unit=(struct Unit *)Unit;
if (Unit->fsru_Open) Unit->fsru_Open(IORequest);
Permit();
return;
}
Permit();
IOReq->io_Error=IOERR_OPENFAIL;
IOReq->io_Device=NULL;
}
void __saveds _UserLibClose(struct FakeSerDevice *FakeSerBase,void *IORequest)
{
struct FSRUnit *Unit;
struct IORequest *IOReq;
void *SysBase;
SysBase=*((void **)0x00000004);
if (!FakeSerBase || !IORequest) return;
IOReq=IORequest;
Unit=(struct FSRUnit *)IOReq->io_Unit;
if (!Unit) return;
if (Unit->fsru_Close) Unit->fsru_Close(IORequest);
return;
}